#include "LFOSCommon.h"
#include "EdgeDetection.h"
#include <iostream>
#include <fstream>

using namespace std;

EdgeDetection::EdgeDetection()
{
	int x,y;
	//initialize outer edge of frame to false

	//top row first
	y=0;
	for(x=0; x < COLS; ++x)
	{
		edgeFrame[ROW_COL_TO_INDEX(x,y)] = false;
	}

	//bottom row
	y=ROWS-1;
	for(x=0; x < COLS; ++x)
	{
		edgeFrame[ROW_COL_TO_INDEX(x,y)] = false;
	}

	//left column
	x=0;
	for(y=0; y < ROWS; ++y)
	{
		edgeFrame[ROW_COL_TO_INDEX(x,y)] = false;
	}

	//right column
	x=COLS-1;
	for(y=0; y < ROWS; ++y)
	{
		edgeFrame[ROW_COL_TO_INDEX(x,y)] = false;
	}
}

bool* EdgeDetection::ProcessEdges(unsigned char* frame, Point* edgePoints, int& numEdges)
{
	int sumx, sumy;
	int temp[PIXELS];
	int average = 0;
	int threshold;
	bool b1, b2, b3, b4;

	numEdges = 0;
	for(int y=0; y < ROWS; ++y)
		for(int x=0; x < COLS; ++x)
		{
			if (y == 0 || y == (ROWS-1) ||
					x == 0 || x == (COLS-1))
				//temp[ROW_COL_TO_INDEX(x,y)] = frame[ROW_COL_TO_INDEX(x,y)];
				temp[ROW_COL_TO_INDEX(x,y)] = 0;
			else
			{
//				temp[ROW_COL_TO_INDEX(x,y)] = (frame[ROW_COL_TO_INDEX(x-1,y-1)]*GAUSS_0_0 +
//						frame[ROW_COL_TO_INDEX(x,y-1)]*GAUSS_0_1 +
//						frame[ROW_COL_TO_INDEX(x+1,y-1)]*GAUSS_0_2 +
//						frame[ROW_COL_TO_INDEX(x-1,y)]*GAUSS_1_0 +
//						frame[ROW_COL_TO_INDEX(x,y)]*GAUSS_1_1 +
//						frame[ROW_COL_TO_INDEX(x+1,y)]*GAUSS_1_2 +
//						frame[ROW_COL_TO_INDEX(x-1,y+1)]*GAUSS_2_0 +
//						frame[ROW_COL_TO_INDEX(x,y+1)]*GAUSS_2_1 +
//						frame[ROW_COL_TO_INDEX(x+1,y+1)]*GAUSS_2_2)/GAUSS_COEFF;
				sumx = (frame[ROW_COL_TO_INDEX(x-1,y-1)]*GX_0_0 +
						frame[ROW_COL_TO_INDEX(x,y-1)]*GX_0_1 +
						frame[ROW_COL_TO_INDEX(x+1,y-1)]*GX_0_2 +
						frame[ROW_COL_TO_INDEX(x-1,y)]*GX_1_0 +
						frame[ROW_COL_TO_INDEX(x,y)]*GX_1_1 +
						frame[ROW_COL_TO_INDEX(x+1,y)]*GX_1_2 +
						frame[ROW_COL_TO_INDEX(x-1,y+1)]*GX_2_0 +
						frame[ROW_COL_TO_INDEX(x,y+1)]*GX_2_1 +
						frame[ROW_COL_TO_INDEX(x+1,y+1)]*GX_2_2)/8;

				sumy = (frame[ROW_COL_TO_INDEX(x-1,y-1)]*GY_0_0 +
						frame[ROW_COL_TO_INDEX(x,y-1)]*GY_0_1 +
						frame[ROW_COL_TO_INDEX(x+1,y-1)]*GY_0_2 +
						frame[ROW_COL_TO_INDEX(x-1,y)]*GY_1_0 +
						frame[ROW_COL_TO_INDEX(x,y)]*GY_1_1 +
						frame[ROW_COL_TO_INDEX(x+1,y)]*GY_1_2 +
						frame[ROW_COL_TO_INDEX(x-1,y+1)]*GY_2_0 +
						frame[ROW_COL_TO_INDEX(x,y+1)]*GY_2_1 +
						frame[ROW_COL_TO_INDEX(x+1,y+1)]*GY_2_2)/8;

				temp[ROW_COL_TO_INDEX(x,y)] = sumx*sumx + sumy*sumy;
				average = average + temp[ROW_COL_TO_INDEX(x,y)];
			}


		}

	threshold = 4*average/PIXELS;

	for(int y=0; y < ROWS; ++y)
		for(int x=0; x < COLS; ++x)
	{
		//edge thinning
		 if(x == 1)
            b1 = true;
          else
            b1 = temp[ROW_COL_TO_INDEX(x-1,y)] <= temp[ROW_COL_TO_INDEX(x,y)];

          if(x == COLS-1)
            b2 = true;
          else
            b2 = temp[ROW_COL_TO_INDEX(x,y)] > temp[ROW_COL_TO_INDEX(x+1,y)];

          if(y == 1)
            b3 = true;
          else
            b3 = temp[ROW_COL_TO_INDEX(x,y-1)] <= temp[ROW_COL_TO_INDEX(x,y)];

          if(y == ROWS - 1)
            b4 = true;
          else
            b4 = temp[ROW_COL_TO_INDEX(x,y)] > temp[ROW_COL_TO_INDEX(x,y+1)];

		if(temp[ROW_COL_TO_INDEX(x,y)] > threshold && ((b1 && b2) || (b3 && b4)))
		{
			//edgeFrame[i] = true;
			edgeFrame[ROW_COL_TO_INDEX(x,y)] = true;
			edgePoints[numEdges].x = x;
			edgePoints[numEdges++].y = y;
		}
		else
			edgeFrame[ROW_COL_TO_INDEX(x,y)] = false;
	}

//	for(int y=1; y < (ROWS - 1); ++y)
//		for(int x=1; x < (COLS - 1); ++x)
//		{
//			sum = (temp[ROW_COL_TO_INDEX(x-1,y-1)]*H_0_0 +
//					temp[ROW_COL_TO_INDEX(x,y-1)]*H_0_1 +
//					temp[ROW_COL_TO_INDEX(x+1,y-1)]*H_0_2 +
//					temp[ROW_COL_TO_INDEX(x-1,y)]*H_1_0 +
//					temp[ROW_COL_TO_INDEX(x,y)]*H_1_1 +
//					temp[ROW_COL_TO_INDEX(x+1,y)]*H_1_2 +
//					temp[ROW_COL_TO_INDEX(x-1,y+1)]*H_2_0 +
//					temp[ROW_COL_TO_INDEX(x,y+1)]*H_2_1 +
//					temp[ROW_COL_TO_INDEX(x+1,y+1)]*H_2_2)/8;
//
//			if(sum > THRESHOLD)
//				edgeFrame[ROW_COL_TO_INDEX(x,y)] = true;
//			else
//				edgeFrame[ROW_COL_TO_INDEX(x,y)] = false;
//
//		}

	return edgeFrame;
}
